package css.sword.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import css.sword.util.Docrights;
import css.sword.util.HttpClient;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Controller
public class HelloController {
   // static String rootPath = System.getProperty("user.dir");

    static String rootPath = "/opt";
    //template路径
    static String s_templateDir = rootPath + "\\template\\templatedir";

    //安全文档服务器地址
    static String s_serverUrlSecurityDoc = "http://yun.szoa.sz.gov.cn/securitydoc";
    //账号服务器地址
    static String s_serverUrlAccount = "http://yun.szoa.sz.gov.cn/account";
    // yun.szoa.sz.gov.cn/account
    //http://account.szoa.sz.gov.cn

    //用户名密码
    static String s_account = "";
    static String s_password = "";
    static String ca_token = "";


    //安全文档加解密进程路径
//    static String s_secDocHelperPath = rootPath + "\\securitydochelper\\securitydochelper.exe";

    static String s_secDocHelperPath = rootPath + "\\securitydochelper\\securitydochelper.exe";

    //测试文档路径 nonSecuritydoc
    static String s_nonSecurityDocPath = rootPath + "\\testFiles\\no_s.docx";
    static String s_securityDocPath = rootPath + "\\testFiles\\securitydoc.doc";


    //获取权限信息结果文件
    static String s_getPermissionsResultFile = rootPath + "\\testFiles\\getPermissionsResult.txt";

    //修改权限信息结果文件
    static String s_pushPermissionsResultFile = rootPath + "\\testFiles\\pushPermissionsResult.txt";

    //权限信息，json格式字符串
//    static String s_permissions = "";
    static String s_permissions = "{\\\"docrights\\\":[{\\\"principalid\\\":\\\"2\\\",\\\"principaltype\\\":2,\\\"operationids\\\":[2,3,4]}]}";
    static String s_permissions2 = "{\\\"docrights\\\":[{\\\"principalid\\\":\\\"2\\\",\\\"principaltype\\\":2,\\\"operationids\\\":[2,3,4,6,7,8]},{\\\"principalid\\\":\\\"3007\\\",\\\"principaltype\\\":2,\\\"operationids\\\":[2,3,4]}]}";
    //session
    static String s_onlineSession = "";
    static Process p;

    static public int runSecurityDocOperation(String cmd) throws InterruptedException {
        try {
            String outputStr = new String("run command: ") + cmd;
            System.out.println(outputStr);
            p = Runtime.getRuntime().exec(cmd);
            int retval = p.waitFor();
            return retval;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //todo
        }
        return -1;
    }

    //判断文档是否是安全文档
    static public boolean isSecurityDoc(String docpath) {
        boolean isSecurityDoc = false;
        try {
            //命令行参数（每个参数以空格隔开）：exe路径   操作类型   文档路径
            String cmdStr = s_secDocHelperPath + " " + SecurityDocOP.op_isSecurityDoc.ordinal() + " " + docpath;
            int ret = runSecurityDocOperation(cmdStr);
            isSecurityDoc = (ret == 0);
        } catch (Exception e) {
            System.out.println(e.toString());
        }

        return isSecurityDoc;
    }

    //获取安全文档的GUID
    static public String getSecurityDocGUID(String securitydocPath) {
        String guid = "";
        try {
            File tmpFile = File.createTempFile("tmp", ".txt");
            //命令行参数（每个参数以空格隔开）：exe路径   操作类型   文档路径   获取结果的文件路径
            String cmdStr = s_secDocHelperPath + " " + SecurityDocOP.op_getSecurityDocGuid.ordinal() + " " + securitydocPath + " " + tmpFile.getPath();
            int ret = runSecurityDocOperation(cmdStr);
            if (ret == 0) {
                Long fileLength = tmpFile.length();
                byte[] fileContent = new byte[fileLength.intValue()];
                FileInputStream in = new FileInputStream(tmpFile);
                in.read(fileContent);
                in.close();
                guid = new String(fileContent);
            }
            tmpFile.delete();
        } catch (Exception e) {
            System.out.println(e.toString());
        }

        return guid;
    }

    //通过用户名密码获取session
    static public String getSessionByAccount(String account, String password) {
        String session = "";
        try {
            File tmpFile = File.createTempFile("tmp", ".txt");
            //命令行参数（每个参数以空格隔开）：exe路径    操作类型    安全服务器地址   用户名     密码     获取结果的文件路径
            String cmdStr = s_secDocHelperPath + " " + SecurityDocOP.op_getOnlineSession.ordinal() + " " + s_serverUrlAccount
                    + " " + account + " " + password + " " + tmpFile.getPath();
            int ret = runSecurityDocOperation(cmdStr);
            if (ret == 0) {
                Long fileLength = tmpFile.length();
                byte[] fileContent = new byte[fileLength.intValue()];
                FileInputStream in = new FileInputStream(tmpFile);
                in.read(fileContent);
                in.close();
                session = new String(fileContent);
            }
            tmpFile.delete();
        } catch (Exception e) {
            // TODO: handle exception
            System.out.println("getSessionByAccount exception occur!");
            System.out.println(e.toString());
        }

        return session;
    }

    //获取安全文档在服务器对应的docid
    static public int getDocId(String securitydocpath) {
        int docid = -1;
        try {
            File tmpFile = File.createTempFile("tmp", ".txt");
            //命令行参数（每个参数以空格隔开）：exe路径    操作类型    安全服务器地址    用户session  文档路径     获取结果的文件路径
            String cmdStr = s_secDocHelperPath + " " + SecurityDocOP.op_getSecurityDocId.ordinal() + " " + s_serverUrlSecurityDoc
                    + " " + s_onlineSession + " " + securitydocpath + " " + tmpFile.getPath();
            int ret = runSecurityDocOperation(cmdStr);
            if (ret == 0) {
                Long fileLength = tmpFile.length();
                byte[] fileContent = new byte[fileLength.intValue()];
                FileInputStream in = new FileInputStream(tmpFile);
                in.read(fileContent);
                in.close();
                String docidStr = new String(fileContent);
                docidStr = docidStr.replaceAll("\r|\n", "");
                docid = Integer.parseInt(docidStr);
            }
            tmpFile.delete();
        } catch (Exception e) {
            System.out.println(e.toString());
        }

        return docid;
    }

    //将普通文档转为安全文档
    static public int createSecurityDoc(String srcPlainDocPath, String destSecurityDocPath) {
        int result = -1;
        try {
            //命令行参数（每个参数以空格隔开）：exe路径    操作类型    模版文件路径    安全服务器地址    用户session  原普通文档路径    生成的安全文档路径
            String cmdStr = s_secDocHelperPath + " " + SecurityDocOP.op_createSecurityDoc.ordinal() + " " + s_templateDir + " "
                    + s_serverUrlSecurityDoc + " " + s_onlineSession + " " + srcPlainDocPath + " " + destSecurityDocPath;
            result = runSecurityDocOperation(cmdStr);
        } catch (Exception e) {
            System.out.println(e.toString());
        }
        return result;
    }

    //将安全文档转为普通文档
    static public int decryptSecurityDoc(String srcSecurityDocPath, String destPlainDocPath) {
        int result = -1;
        try {
            //命令行参数（每个参数以空格隔开）：exe路径    操作类型    模版文件路径    安全服务器地址    用户session  原安全文档路径    生成的普通文档路径
            String cmdStr = s_secDocHelperPath + " " + SecurityDocOP.op_decryptSecurityDoc.ordinal() + " " + s_templateDir + " "
                    + s_serverUrlSecurityDoc + " " + s_onlineSession + " " + srcSecurityDocPath + " " + destPlainDocPath;
            result = runSecurityDocOperation(cmdStr);
        } catch (Exception e) {
            System.out.println(e.toString());
        }

        return result;
    }

    //获取安全文档的权限信息
    static public int getSecurityDocPermissions(String securitydocpath) {
        int result = -1;
        try {
            //命令行参数（每个参数以空格隔开）：exe路径    操作类型    模版文件路径    安全服务器地址    用户session  安全文档路径    结果文件（权限信息会写入该文件中）
            String cmdStr = s_secDocHelperPath + " " + SecurityDocOP.op_fetchDocPermissions.ordinal() + " " + s_templateDir + " "
                    + s_serverUrlSecurityDoc + " " + s_onlineSession + " " + securitydocpath + " " + s_getPermissionsResultFile;
            result = runSecurityDocOperation(cmdStr);
        } catch (Exception e) {
            System.out.println(e.toString());
        }

        return result;
    }

    //更新安全文档的权限信息
    static public int updateSecurityDocPermissions(String securitydocpath, String newPermissionsJsonStr) {
        int result = -1;
        try {
            //命令行参数（每个参数以空格隔开）：exe路径    操作类型    模版文件路径    安全服务器地址    用户session  安全文档路径    新的权限信息（json格式字符串，需要经过base64编码）  结果文件
            String cmdStr = s_secDocHelperPath + " " + SecurityDocOP.op_pushDocPermissions.ordinal() + " " + s_templateDir + " "
                    + s_serverUrlSecurityDoc + " " + s_onlineSession + " " + securitydocpath + " " + newPermissionsJsonStr
                    + " " + s_pushPermissionsResultFile;
            result = runSecurityDocOperation(cmdStr);
        } catch (Exception e) {
            System.out.println(e.toString());
        }

        return result;
    }

    @RequestMapping("/hello")
    public String hello(Model model, HttpServletRequest request) {
        System.out.println("main begin...");
        String outputStr = "";
//        s_account = request.getParameter("username");
//        s_password = request.getParameter("password");
        ca_token = request.getParameter("token");

        String principalType = request.getParameter("principalType");
        String principalId = request.getParameter("principalId");
        String[] operationIds = request.getParameterValues("operationId");

        if (principalType != null && principalId != null && operationIds.length > 0) {
            Docrights docrights = new Docrights();
            Docrights.DocrightsBean docrightsBean = new Docrights.DocrightsBean();
            docrightsBean.setPrincipaltype(Integer.parseInt(principalType));
            docrightsBean.setPrincipalid(principalId);
            List<Integer> operationList = new ArrayList<Integer>();
            for (int i = 0; i < operationIds.length; i++) {
                operationList.add(i, Integer.parseInt(operationIds[i]));
            }
            docrightsBean.setOperationids(operationList);
            List<Docrights.DocrightsBean> docrightsBeans = new ArrayList<Docrights.DocrightsBean>();
            docrightsBeans.add(0, docrightsBean);

            docrights.setDocrights(docrightsBeans);
            s_permissions = JSON.toJSONString(docrights);
            s_permissions = s_permissions.replace("\"", "\\\"");

        }
        System.out.println("s_permissions:" + s_permissions);

//        String docPath = s_securityDocPath;
        String docPath = s_nonSecurityDocPath;
        model.addAttribute("docPath", docPath);
//        if (s_account != null && s_password != null) {

        ca_token = "AQIC5wM2LY4SfcxM6BOEzDiUC9F3LzMDpefKvgRJO0A7IzM.*AAJTSQACMDEAAlNLABM2MzM4MTI2NTMzMDQwODQ3Mzc2*";
        String rsp = GetSession(ca_token);
        s_onlineSession = rsp;
        System.out.println("GetSession:"+rsp);
//            JSONArray jsonArray = GetWpsSid("test,dsr");
//            System.out.println(jsonArray);


        // test账号wpsSid
//          s_onlineSession = "7c2091186f0a15160b073307c446f46979253d930000000bbf";
        outputStr = new String("session = ") + s_onlineSession;
        model.addAttribute("s_onlineSession", outputStr);
        System.out.println(outputStr);
        //判断文档是否是安全文档

//
        if (isSecurityDoc(docPath)) {
            outputStr = docPath + " is a security doc!";
            System.out.println(outputStr);
            model.addAttribute("isSecurityDoc", outputStr);

            //获取安全文档GUID
            String guid = getSecurityDocGUID(docPath);
            outputStr = new String("GUID = ") + guid;
            System.out.println(outputStr);
            model.addAttribute("securityDocGUID", outputStr);


            //获取安全文档在服务器对应的docid
            int docid = getDocId(docPath);
            outputStr = new String("DocId = ") + docid;
            System.out.println(outputStr);
            model.addAttribute("securityDocId", outputStr);


            //获取安全文档的权限信息，具体权限结果写在文件s_getPermissionsResultFile里面
            int ret = getSecurityDocPermissions(docPath);
            if (ret == 0) {
                outputStr = new String("get permissions succeed, result file path is : ") + s_getPermissionsResultFile;
                System.out.println(outputStr);
                model.addAttribute("securityDocPermissions", outputStr);
            } else {
                outputStr = new String("get permissions failed, result file path is : ") + s_getPermissionsResultFile;
                System.out.println(outputStr);
                model.addAttribute("securityDocPermissions", outputStr);
            }

            //更新安全文档权限信息，操作结果写在文件s_pushPermissionsResultFile里面，成功的话文件内容为null,否则会写入失败原因
            ret = updateSecurityDocPermissions(docPath, s_permissions);
            if (ret == 0) {
                outputStr = new String("push permissions succeed, result file path is : ") + s_pushPermissionsResultFile;
                System.out.println(outputStr);
                model.addAttribute("updateSecurityDocPermissions", outputStr);
            } else {
                outputStr = new String("push permissions failed, result file path is : ") + s_pushPermissionsResultFile;
                System.out.println(outputStr);
                model.addAttribute("updateSecurityDocPermissions", outputStr);
            }

            //解密安全文档为普通文档
            String destPlainDocPath = s_nonSecurityDocPath;
            ret = decryptSecurityDoc(docPath, destPlainDocPath);
            if (ret == 0) {
                outputStr = new String("decrypt security doc succeed, result file path is : ") + destPlainDocPath;
                System.out.println(outputStr);
                model.addAttribute("decryptSecurityDoc", outputStr);
            } else {
                outputStr = new String("decrypt security doc failed");
                System.out.println(outputStr);
                model.addAttribute("decryptSecurityDoc", outputStr);
            }

        } else {
            outputStr = docPath + " is not a security doc!";
            System.out.println(outputStr);
            model.addAttribute("isSecurityDoc", outputStr);
            //将普通文档转为安全文档
            String destSecurityDocPath = s_securityDocPath;
            int ret = createSecurityDoc(docPath, destSecurityDocPath);
            if (ret == 0) {
                outputStr = new String("create security doc succeed, result file path is : ") + destSecurityDocPath;
                System.out.println(outputStr);
        model.addAttribute("createSecurityDoc", outputStr);
    } else {
        outputStr = new String("create security doc failed");
        System.out.println(outputStr);
        model.addAttribute("createSecurityDoc", outputStr);
    }
}
//        }

        return "hello";
    }
//
//    //处理文件上传
//    @RequestMapping(value = "/upload", method = RequestMethod.POST)
//    public @ResponseBody
//    String uploadImg(@RequestParam("file") MultipartFile file,Model model,
//                     HttpServletRequest request) {
//        String contentType = file.getContentType();
//        String fileName = file.getOriginalFilename();
////        String filePath = request.getSession().getServletContext().getRealPath("imgupload/");
//        String filePath = rootPath + "\\testFiles\\";
//        model.addAttribute("upload", filePath);
//        try {
//            uploadFile(file.getBytes(), filePath, fileName);
//        } catch (Exception e) {
//            // TODO: handle exception
//        }
//        //返回json
//        return "hello";
//    }

    //安全文档相关操作
    static enum SecurityDocOP {
        op_isSecurityDoc,                //判断文档是否是安全文档
        op_getSecurityDocGuid,           //获取安全文档的guid
        op_getSecurityDocId,             //获取安全文档在服务器对应的docid
        op_getOnlineSession,             //通过用户名密码获取session
        op_decryptSecurityDoc,           //解密安全文档
        op_createSecurityDoc,            //创建安全文档
        op_fetchDocPermissions,          //获取文档的权限信息
        op_pushDocPermissions            //更新文档的权限信息
    }

    public static void uploadFile(byte[] file, String filePath, String fileName) throws Exception {
        File targetFile = new File(filePath);
        if (!targetFile.exists()) {
            targetFile.mkdirs();
        }
        FileOutputStream out = new FileOutputStream(filePath + fileName);
        out.write(file);
        out.flush();
        out.close();

    }

    // 根据ca的token 找到wpssid
    private static String GetSession(String token) {
        String rsp = "";
//        String urlString = "http://yunselftest.szoa.sz.gov.cn/secure/session/user?token=" + token;
        String urlString = "http://yun.szoa.sz.gov.cn/secure/session/user?token=" + token;
        rsp = HttpClient.doGet(urlString);
        System.out.println("GetSession rsp:" + rsp);
        JSONObject jsonObject = JSONObject.parseObject(rsp);
        String data = jsonObject.getString("data");
        return data;
    }

    // 根据三方name找到wps的用户id
    private static JSONArray GetWpsSid(String account) {
        String rsp = "";
        String urlString = "http://yunselftest.szoa.sz.gov.cn/secure/userid/user?username=" + "test,dsr";
        rsp = HttpClient.doGet(urlString);
        JSONObject jsonObject = JSONObject.parseObject(rsp);
        JSONArray data = jsonObject.getJSONArray("data");
        return data;
    }
}
